Skip to content

fix(changelog): remove stale Unreleased entry and guard against manual entries#5369

Merged
Flash0ver merged 10 commits into
mainfrom
changelog-unreleased-ci-guard
Jul 13, 2026
Merged

fix(changelog): remove stale Unreleased entry and guard against manual entries#5369
Flash0ver merged 10 commits into
mainfrom
changelog-unreleased-ci-guard

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Why the 6.7.0 changelog broke

The 6.7.0 release shipped with a single changelog entry despite dozens of merged PRs.

Root cause: the repo generates its changelog automatically via craft (changelogPolicy: auto in .craft.yml). Craft only regenerates the ## Unreleased section when it is empty (prepare.tsif (!changeset.body) guards the git-based generation, and the body is .trim()-ed first). A stale, hand-written entry (#5025) had been left under ## Unreleased, so craft saw non-empty content, skipped generation entirely, and just renamed ## Unreleased## 6.7.0. Everything else was silently dropped.

That stale line got there because CONTRIBUTING.md still instructed contributors to hand-add ## Unreleased entries — contradicting the auto policy (and AGENTS.md/CLAUDE.md, which already say do not add changelogs manually).

How changelog entries are meant to be produced

Under changelogPolicy: auto, nobody edits CHANGELOG.md. craft builds each entry one of two ways:

  1. From the commit message / PR title — the default. A feat: PR becomes a Feature, a fix: PR a Fix, etc.
  2. From a ### Changelog Entry section in the PR description — if present, craft uses that text verbatim instead of the title, which lets a PR provide a richer or multi-line entry (or several entries). See craft docs.

Either way, the ## Unreleased section must stay empty so craft regenerates it at release time.

Changes

  • CHANGELOG.md — remove the stale manual ## Unreleased entry so craft regenerates 6.7.0 from git history (the feat: Add exponential backoff and log deduplication to Spotlight #5025 feature is still captured — it's a feat: commit in range).
  • .github/workflows/changelog-guard.yml + scripts/verify-changelog.sh — a Changelog Guard check that fails any PR leaving content under ## Unreleased. It mirrors craft's own emptiness test: any non-whitespace content fails (a bullet, or even a bare ### Features sub-heading), while an empty ## Unreleased heading passes. Reports the offending CHANGELOG.md line numbers. Runnable locally: ./scripts/verify-changelog.sh.
  • CONTRIBUTING.md — replace the stale "add a ## Unreleased heading" instructions with the automatic-changelog policy, documenting both entry mechanisms above.
  • AGENTS.md — add a Getting Started note to check out submodules first (./dev.cs cleanslate); without them, tooling like generate-solution-filters.ps1 silently drops projects from the *.slnf files.
  • Sentry.slnx / .generated.NoMobile.slnx — register the new workflow and script in the solution.

Follow-up (not in this PR)

The 6.7.0 release itself needs to be re-cut after this lands so craft regenerates the full changelog. Consider making Changelog Guard a required status check.

🤖 Generated with Claude Code

…l entries

The changelog is generated automatically at release time by craft
(changelogPolicy: auto). craft only regenerates the "## Unreleased" section
when it is empty, so a single leftover manual entry suppresses generation and
drops every other change from the release notes. This is what broke the 6.7.0
release, which shipped with a single entry (the stale #5025 line) despite dozens
of merged PRs.

- Remove the stale manual entry from CHANGELOG.md so craft regenerates 6.7.0
  from git history.
- Add a Changelog Guard workflow + scripts/verify-changelog.sh that fails any
  PR adding a manual entry under "## Unreleased".
- Update CONTRIBUTING.md, which still instructed contributors to hand-add
  "## Unreleased" entries (the source of the stale line), to reflect the
  automatic changelog policy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread CONTRIBUTING.md Outdated
@jamescrosswell
jamescrosswell marked this pull request as ready for review July 10, 2026 02:24
@github-actions github-actions Bot added the risk: high PR risk score: high label Jul 10, 2026
Comment thread .github/workflows/changelog-guard.yml
Comment thread scripts/verify-changelog.sh Outdated
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.24%. Comparing base (373e860) to head (b9cdf5f).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #5369   +/-   ##
=======================================
  Coverage   74.24%   74.24%           
=======================================
  Files         509      509           
  Lines       18412    18412           
  Branches     3604     3604           
=======================================
  Hits        13670    13670           
  Misses       3869     3869           
  Partials      873      873           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Flash0ver Flash0ver added the skip-changelog Suppress automatic changelog generation via Craft label Jul 10, 2026
Comment thread CONTRIBUTING.md
Comment thread scripts/verify-changelog.sh Outdated
Comment thread scripts/verify-changelog.sh Outdated
Comment thread .github/workflows/changelog-guard.yml
Comment thread scripts/verify-changelog.sh Outdated
Comment thread scripts/verify-changelog.sh Outdated
jamescrosswell and others added 3 commits July 13, 2026 10:04
…t bullets

craft trims the Unreleased section body and skips auto-generation whenever it is
non-empty (`if (!changeset.body)` after `.trim()`). The previous check only
failed on bullet lines, so a heading-only leftover (e.g. a bare "### Features")
would still suppress generation and drop the rest of the release notes. Match
craft's behaviour exactly: fail on any non-whitespace content under
"## Unreleased"; a bare/empty heading still passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c5771de. Configure here.

Comment thread scripts/verify-changelog.sh Outdated
jamescrosswell and others added 5 commits July 13, 2026 10:10
craft supports richer changelog entries via a '### Changelog Entry' section in
the PR description (used verbatim instead of the PR title). Point contributors
at it from both CONTRIBUTING.md and the guard's failure message.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Stefan Pölz <38893694+Flash0ver@users.noreply.github.com>
Co-authored-by: James Crosswell <jamescrosswell@users.noreply.github.com>
…lution

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Without recursively-checked-out submodules under modules/, builds and tooling
break in confusing ways (e.g. generate-solution-filters.ps1 silently drops the
missing projects from the *.slnf files, as happened while preparing this PR).
Point contributors/agents at ./dev.cs cleanslate up front.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntries

The previous check grepped the extracted section body, so reported line numbers
were offset from the actual file. Emit real file line numbers (awk NR) in a
single pass instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@Flash0ver Flash0ver left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤘

@Flash0ver
Flash0ver merged commit b302e47 into main Jul 13, 2026
41 checks passed
@Flash0ver
Flash0ver deleted the changelog-unreleased-ci-guard branch July 13, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high skip-changelog Suppress automatic changelog generation via Craft

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants